package com.changwen.currentactivity.accessibility;

import android.accessibilityservice.AccessibilityService;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import java.util.ArrayList;
import java.util.List;

/**
 * @author lcw
 * @date 2019/4/5
 * @desc
 */
public abstract class BaseAcbService extends AccessibilityService implements IAcbAction {

    private static final String TAG = "AccessibilityService";
//    private AccessibilityManager mManager;

    public BaseAcbService() {
//        mManager = (AccessibilityManager) Utils.getApp().getApplicationContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
    }

    @Override
    public void onInterrupt() {
    }

//GLOBAL_ACTION_POWER_DIALOG //关机菜单
//GLOBAL_ACTION_LOCK_SCREEN //锁屏

    /**
     * 模拟后退事件
     */
    @Override
    public void performBack() {
        performGlobalAction(GLOBAL_ACTION_BACK);
    }

    /**
     * 模拟home
     */
    @Override
    public void performHome() {
        performGlobalAction(GLOBAL_ACTION_HOME);
    }

    /**
     * 模拟最近任务
     */
    @Override
    public void performEcents() {
        performGlobalAction(GLOBAL_ACTION_RECENTS);
    }

    /**
     * 模拟拉出通知栏
     */
    @Override
    public void performNotifications() {
        performGlobalAction(GLOBAL_ACTION_NOTIFICATIONS);
    }

    /**
     * 模拟向上滚动
     */
    @Override
    public void performScrollUp() {
        performGlobalAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
    }

    /**
     * 模拟向下滚动
     */
    @Override
    public void performScrollDown() {
        performGlobalAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
    }

    /**
     * 模拟view点击
     *
     * @param nodeInfo
     */
    @Override
    public boolean performViewClick(AccessibilityNodeInfo nodeInfo) {
        if (nodeInfo == null) {
            return false;
        }
        while (nodeInfo != null) {
            if (nodeInfo.isClickable()) {
                nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                return true;
            }
            nodeInfo = nodeInfo.getParent();
        }
        return false;
    }

    /**
     * 根据文本获取view控件
     *
     * @param text
     * @return
     */
    @Override
    public AccessibilityNodeInfo findViewByText(String text) {
        return findViewByText(text, false);
    }

    /**
     * 根据文本获取view控件
     *
     * @param text
     * @param clickable
     * @return
     */
    @Override
    public AccessibilityNodeInfo findViewByText(String text, boolean clickable) {
        AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
        if (accessibilityNodeInfo == null) {
            return null;
        }
        List<AccessibilityNodeInfo> nodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByText(text);
        if (nodeInfoList != null && !nodeInfoList.isEmpty()) {
            for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
                if (nodeInfo != null && (nodeInfo.isClickable() == clickable)) {
                    return nodeInfo;
                }
            }
        }
        return null;
    }

    /**
     * 根据viewId获取view控件
     *
     * @param viewId
     * @return
     */
    @Override
    public AccessibilityNodeInfo findViewByViewId(String viewId) {
        return findViewByViewId(viewId, true);
    }

    /**
     * 根据viewId获取view控件
     *
     * @param viewId
     * @param clickable
     * @return
     */
    @Override
    public AccessibilityNodeInfo findViewByViewId(String viewId, boolean clickable) {
        AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
        if (accessibilityNodeInfo == null) {
            return null;
        }
        List<AccessibilityNodeInfo> nodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByViewId(viewId);
        if (nodeInfoList != null && !nodeInfoList.isEmpty()) {
            for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
                if (nodeInfo != null && (nodeInfo.isClickable() == clickable)) {
                    return nodeInfo;
                }
            }
        }
        return null;
    }

    /**
     * 点击指定text的view
     *
     * @param text
     */
    @Override
    public boolean clickViewByText(String text) {
        AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
        if (accessibilityNodeInfo == null) {
            Log.i(TAG, "clickViewByText accessibilityNodeInfo is null");
            return false;
        }
        List<AccessibilityNodeInfo> nodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByText(text);
        if (nodeInfoList != null && !nodeInfoList.isEmpty()) {
            for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
                if (nodeInfo != null) {
                    if (performViewClick(nodeInfo)) {
                        Log.d(TAG, "点击了 text >>>>>> " + text);
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public boolean clickViewByText2(String text) {
        AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
        if (accessibilityNodeInfo == null) {
            Log.i(TAG, "clickViewByText accessibilityNodeInfo is null");
            return false;
        }
        List<AccessibilityNodeInfo> nodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByText(text);
        if (nodeInfoList != null && !nodeInfoList.isEmpty()) {
            for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
                if (nodeInfo != null && nodeInfo.getText() != null && text.equals(nodeInfo.getText().toString())) {
                    if (performViewClick(nodeInfo)) {
                        Log.d(TAG, "点击了 text >>>>>> " + text);
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 点击指定text的view(WebView内部)
     *
     * @param text
     */
    @Override
    public boolean clickViewByTextInWebView(String text) {
        AccessibilityNodeInfo nodeInfo = recurseFindByText(text);
        if (nodeInfo != null) {
            if (performViewClick(nodeInfo)) {
                Log.d(TAG, "点击了 text (WebView内部) >>>>>> " + text);
                return true;
            }
        }
        return false;
    }

    /**
     * 点击指定text的view(WebView内部)
     *
     * @param text
     */
    @Override
    public boolean clickViewByTextInWebViewToList(String text) {
        List<AccessibilityNodeInfo> nodeInfoList = recurseFindByTextToList(text);
        if (nodeInfoList != null && nodeInfoList.size() > 0) {
            int clickCount = 0;
            for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
                if (nodeInfo != null) {
                    if (performViewClick(nodeInfo)) {
                        Log.d(TAG, "点击了 text (WebView内部) List >>>>>> " + text);
                        clickCount++;
                    }
                }
            }
            return clickCount == nodeInfoList.size();
        }
        return false;
    }

    /**
     * 点击指定viewId的view
     *
     * @param viewId
     */
    @Override
    public boolean clickViewByViewId(String viewId) {
        AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
        if (accessibilityNodeInfo == null) {
            Log.i(TAG, "accessibilityNodeInfo is null");
            return false;
        }
        List<AccessibilityNodeInfo> nodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByViewId(viewId);
        if (nodeInfoList != null && !nodeInfoList.isEmpty()) {
            for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
                if (nodeInfo != null) {
                    if (performViewClick(nodeInfo)) {
                        Log.d(TAG, "点击了 viewId >>>>>> " + viewId);
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 模拟文本框输入
     *
     * @param nodeInfo
     * @param text
     */
    @Override
    public void performInputText(AccessibilityNodeInfo nodeInfo, String text) {
        if (nodeInfo == null) {
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Bundle arguments = new Bundle();
            arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text);
            nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
            ClipData clip = ClipData.newPlainText("label", text);
            clipboard.setPrimaryClip(clip);
            nodeInfo.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
            nodeInfo.performAction(AccessibilityNodeInfo.ACTION_PASTE);
        }
    }

    /**
     * 递归寻找AccessibilityNodeInfo  这里主要用于寻找webView 内部的文本
     * 适用于 文本唯一的控件
     *
     * @param target
     * @return
     */
    @Override
    public AccessibilityNodeInfo recurseFindByText(String target) {
        return recurseFindByText(getRootInActiveWindow(), target);
    }

    /**
     * 递归寻找AccessibilityNodeInfo  这里主要用于寻找webView 内部的文本
     * 适用于 文本唯一的控件
     *
     * @param nodeInfo
     * @param target
     * @return
     */
    @Override
    public AccessibilityNodeInfo recurseFindByText(AccessibilityNodeInfo nodeInfo, String target) {

        if (nodeInfo != null && nodeInfo.getChildCount() == 0) {
            if (((nodeInfo.getText() != null && nodeInfo.getText().toString().contains(target))
                    || (nodeInfo.getContentDescription() != null && nodeInfo.getContentDescription().toString().contains(target)))) {
                return nodeInfo;
            } else {
                return null;
            }
        } else {
            if (nodeInfo == null) {
                return null;
            }

            for (int i = 0; i < nodeInfo.getChildCount(); i++) {
                AccessibilityNodeInfo child = nodeInfo.getChild(i);
                AccessibilityNodeInfo isTaget = recurseFindByText(child, target);
                if (isTaget != null) {
                    return isTaget;
                }
            }
            return null;
        }
    }

    /**
     * 递归寻找AccessibilityNodeInfo  这里主要用于寻找webView 内部的文本
     * 找到控件添加进List
     * 这里属于模糊匹配， 只要包含target即可
     *
     * @param target
     * @return
     */
    @Override
    public List<AccessibilityNodeInfo> recurseFindByTextToList(String target) {
        return recurseFindByTextToList(getRootInActiveWindow(), target);
    }

    /**
     * 递归寻找AccessibilityNodeInfo  这里主要用于寻找webView 内部的文本
     * 找到控件添加进List
     * 这里属于模糊匹配， 只要包含target即可
     *
     * @param nodeInfo
     * @param target
     * @return
     */
    @Override
    public List<AccessibilityNodeInfo> recurseFindByTextToList(AccessibilityNodeInfo nodeInfo, String target) {

        List<AccessibilityNodeInfo> mInfos = new ArrayList<>();

        if (nodeInfo != null && nodeInfo.getChildCount() == 0) {

            if (((nodeInfo.getText() != null && nodeInfo.getText().toString().contains(target))
                    || (nodeInfo.getContentDescription() != null && nodeInfo.getContentDescription().toString().contains(target)))) {
                mInfos.add(nodeInfo);
            }
        } else {
            if (nodeInfo == null) {
                return mInfos;
            }
            for (int i = 0; i < nodeInfo.getChildCount(); i++) {
                AccessibilityNodeInfo child = nodeInfo.getChild(i);
                mInfos.addAll(recurseFindByTextToList(child, target));
            }
        }
        return mInfos;
    }

    /**
     * 根据widget获取view控件 (android.widget.EditText)
     *
     * @param widgetFullName
     * @return
     */
    @Override
    public List<AccessibilityNodeInfo> findViewByWidget(String widgetFullName) {
        return findViewByWidget(getRootInActiveWindow(), widgetFullName);
    }

    /**
     * 根据widget获取view控件 (android.widget.EditText)
     *
     * @param nodeInfo
     * @param widgetFullName
     * @return
     */
    @Override
    public List<AccessibilityNodeInfo> findViewByWidget(AccessibilityNodeInfo nodeInfo, String widgetFullName) {
        List<AccessibilityNodeInfo> accessibilityNodeInfos = new ArrayList<>();
        if (nodeInfo == null) {
            return null;
        }

        if (nodeInfo.getChildCount() > 0) {
            for (int i = 0; i < nodeInfo.getChildCount(); i++) {
                AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
                if (childNodeInfo != null) {
                    Log.i(TAG, "------ nodeInfo ------ ClassName == " + childNodeInfo.getClassName() + "  text == " + childNodeInfo.getText() + "  ContentDescription == " + childNodeInfo.getContentDescription());
                    if (childNodeInfo.getClassName() != null && widgetFullName.equals(childNodeInfo.getClassName().toString())) {
                        accessibilityNodeInfos.add(childNodeInfo);
                    } else {
                        accessibilityNodeInfos.addAll(findViewByWidget(childNodeInfo, widgetFullName));
                    }
                }

            }
        }
        return accessibilityNodeInfos;
    }

    /**
     * 根据ContentDescription获取view控件
     *
     * @param contentDesc
     * @return
     */
    @Override
    public List<AccessibilityNodeInfo> findViewByContentDesc(String contentDesc) {
        return findViewByContentDesc(getRootInActiveWindow(), contentDesc);
    }

    /**
     * 根据ContentDescription获取view控件
     *
     * @param nodeInfo
     * @param contentDesc
     * @return
     */
    @Override
    public List<AccessibilityNodeInfo> findViewByContentDesc(AccessibilityNodeInfo nodeInfo, String contentDesc) {
        List<AccessibilityNodeInfo> accessibilityNodeInfos = new ArrayList<>();
        if (nodeInfo == null) {
            return null;
        }

        if (nodeInfo.getChildCount() > 0) {
            for (int i = 0; i < nodeInfo.getChildCount(); i++) {
                AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
                if (childNodeInfo != null) {
                    Log.i(TAG, "------ nodeInfo ------ ClassName == " + childNodeInfo.getClassName() + "  text == " + childNodeInfo.getText() + "  ContentDescription == " + childNodeInfo.getContentDescription());
                    if (childNodeInfo.getContentDescription() != null && contentDesc.equals(childNodeInfo.getContentDescription().toString())) {
                        accessibilityNodeInfos.add(childNodeInfo);
                    } else {
                        accessibilityNodeInfos.addAll(findViewByContentDesc(childNodeInfo, contentDesc));
                    }
                }
            }
        }
        return accessibilityNodeInfos;
    }


    protected boolean isIgnore = false;

    protected void ignore() {
        isIgnore = true;
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                isIgnore = false;
            }
        }, 1000);
    }

}
